#pragma once

template <class ElementType>
class LinkedList
{
	struct Node;
	typedef Node* NodePtr;
	
	struct Node
	{
		NodePtr Next;
		ElementType Data;
	};

	public:
		LinkedList() : Head(NULL)
		{

		}

		virtual ~LinkedList()
		{
			Clear();
		}

		void PushFront(ElementType data)
		{
			NodePtr node = new Node();
			node->Data = data;
			node->Next = Head;
			Head = node;
		}

		bool Find(const ElementType &data) const
		{
			NodePtr current = Head;

			while(current != NULL)
			{
				if(current->Data == data)
				{
					break;
				}
				current = current->Next;
			}

			return (current != NULL);
		}

		void Remove(ElementType data)
		{
			NodePtr current = Head;

			if(current->Data == data)
			{
				Head = current->Next;
				delete(current);
				return;
			}
			
			while(current->Next)
			{
				if(current->Next->Data == data)
				{
					NodePtr deleteNode = current->Next;
					current->Next = current->Next->Next;
					delete(deleteNode);
					break;
				}
				current = current->Next;
			}
		}

		void Clear()
		{
			NodePtr current = Head;

			while(current)
			{
				Head = current->Next;
				delete(current);
				current = Head;
			}
		}

	private:
		NodePtr Head;
		NodePtr Tail;
};